#ifndef ___fat32_conexiones_disco

#define ___fat32_conexiones_disco 1

#include "f32_conf.c"
#include "f32_econ.c"
#include "mtlib.c"
#include "operbits.c"

int fat32_crear_conexiones_disco(void);
void fat32_crear_conexion_disco(unsigned short, mti_direccion_ipv4, unsigned short);
void fat32_esperar_handshakes(mti_direccion_ipv4, unsigned short);
unsigned short fat32_handshakes_remanentes(void);

int fat32_crear_conexiones_disco (void) {
  unsigned short cantconexiones = fat32_cantidad_conexiones_a_crear();
  if (!cantconexiones) cantconexiones = 20; // valor por default
  fat32_cantidad_conexiones = cantconexiones;
  fat32_conexiones_disco = malloc(cantconexiones * sizeof(unsigned int));
  fat32_conexiones_ocupadas = malloc((cantconexiones + 3) / 4);
  mti_direccion_ipv4 ip = fat32_direccion_conexion_disco();
  unsigned short puerto = fat32_puerto_conexion_disco();
  unsigned short num;
  for (num = 0; num < cantconexiones; num ++)
    fat32_crear_conexion_disco(num, ip, puerto);
  fat32_esperar_handshakes(ip, puerto);
  return cantconexiones;
}

void fat32_crear_conexion_disco (unsigned short numConexion, mti_direccion_ipv4 ipConexion, unsigned short puertoConexion) {
  unsigned int conexion = 0;
  while (!conexion) conexion = mtf_conectar(fat32_centro_mensajes, MTP_IPV4, ipConexion, puertoConexion);
  fat32_conexiones_disco[numConexion] = conexion;
  fat32_conexiones_ocupadas[numConexion / 4] = establecerBits(fat32_conexiones_ocupadas[numConexion / 4], (numConexion % 4) * 2, 2,
                                                              ECON_ESPERA_HANDSHAKE);
  mtf_enviar_handshake(fat32_centro_mensajes, conexion, 0, NULL);
}

void fat32_esperar_handshakes (mti_direccion_ipv4 IPconexiones, unsigned short puertoConexiones) {
  while (fat32_handshakes_remanentes()) {
    while (!mtf_recibir_mensajes(fat32_centro_mensajes));
    mti_mensaje mensaje = mtf_siguiente_mensaje(fat32_centro_mensajes);
    if ((mensaje.categoria != MTA_HANDSHAKE) && (mensaje.categoria != MTA_CERRAR)) {
      mtf_descartar_mensaje(fat32_centro_mensajes, mensaje.codigo);
      continue;
    }
    unsigned short posicion;
    unsigned short pr = 65535;
    for (pr = 0; pr < fat32_cantidad_conexiones; pr ++)
      if (fat32_conexiones_disco[pr] == mensaje.remitente) posicion = pr;
    if (posicion == 65535) {
      mtf_descartar_mensaje(fat32_centro_mensajes, mensaje.codigo);
      continue;
    }
    if ((mensaje.categoria == MTA_CERRAR) || ((mensaje.categoria == MTA_HANDSHAKE) && mensaje.tipo)) {
      mtf_descartar_mensaje(fat32_centro_mensajes, mensaje.codigo);
      fat32_crear_conexion_disco(posicion, IPconexiones, puertoConexiones);
      continue;
    }
    fat32_conexiones_ocupadas[posicion / 4] = establecerBits(fat32_conexiones_ocupadas[posicion / 4], (posicion % 4) * 2, 2, ECON_LIBRE);
  }
}

unsigned short fat32_handshakes_remanentes (void) {
  unsigned short cant = 0;
  unsigned short pos;
  for (pos = 0; pos < fat32_cantidad_conexiones; pos ++)
    if (fat32_estado_conexion(pos) == ECON_ESPERA_HANDSHAKE)
      cant ++;
  return cant;
}

#endif